import re
class SearchText:
    """
    ALL: retorna todos os registros
    <campo>[=<>]<valor> => Retorna todos os registros fazendo match com campo, operador e valor
    texto => Retorna todos os registros fazendo match do texto com os campos do tipo String
    """
    def __init__(self, session, table_schema, schema_object):
        self.table_schema = table_schema
        self.schema_object = schema_object
        self.session = session
        c = re.compile 
        self.list_regexp = (('filter', c('^(?P<attr>\w+)(?P<oper>[><=])(?P<value>\w+)(\[(?P<start>\d+):(?P<end>\d+)\])?$')),
                            ('text'  , c('^(?P<text>.+)$'))
                           )
    
    def execute_filter(self, match):
        oper = match.group('oper')
        attr = match.group('attr')
        value = match.group('value')
        start = eval(str(match.group('start')))
        end = eval(str(match.group('end')))
        string_query = '%s%s"%s"' % (attr, oper, value)
        query = self.session.query(self.table_schema).filter(string_query)
        if start and end:
            query = query.slice(start, end) 
        return query
    
    def execute_text(self, match):
        table_name = self.table_schema.__tablename__
        text = match.group('text')
        columns_name = [column.name for column in self.schema_object.columns if type(column.type) in [sqlalchemy.String]]
        string_query = ''
        for column_name in columns_name:
            string_query+='%(table)s_%(column_name)s like "%%%(text)s%%" or ' % dict(table = table_name, column_name=column_name, text=text)
        string_query = string_query[:-4]
        query = self.session.query(self.table_schema).filter(string_query)
        return query
    def execute_all(self):
        return self.session.query(self.table_schema).all()

    def get_operacao(self, string_search):
        query_operacao = None
        for key, regexp in self.list_regexp:
            match = regexp.match(string_search)
            if match:
                query_operacao = key
                break
        return query_operacao, match
    
    def search(self, string_search):
        query_operacao, match = self.get_operacao(string_search)
        
        if string_search.upper()=='ALL':
            return self.execute_all() 

        if query_operacao == 'filter':
            return self.execute_filter(match)

        if query_operacao == 'text':
            return self.execute_text(match)
